/**
 * CS 340 Fatboy Mafia Team
 */
package fatboy.communication;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;
import java.util.Scanner;

import fatboy.addons.PrintOut;
import fatboy.hypeerweb.Connection;
import fatboy.hypeerweb.Node;
import fatboy.hypeerweb.NodeAddress;

/**
 * @author Ilya Vinogradov
 *
 */
public class Phase3Driver {

	private static final int FINALCOUNT = 128;
	
	/**
	 * The way we are testing our multi threaded instance of our hypeerweb
	 * there are two ways to call it first no arguments which will set up a
	 * hypeerweb and let you give commands to add to it.  the second is
	 * with two parameters the first being a computer naem and the second being a
	 * pert number where a hypeerweb is setup that will connect to it.
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
/*
		if(args.length == 1){
			Driver();
			//System.exit(0);
		}
		if(args.length == 2){
			Client(args);
			//System.exit(0);
		}
*/
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		
		Connection hypeerweb = new Connection();
		if(args.length == 2){
			hypeerweb.terminate();
			hypeerweb = new Connection(args[0],args[1]);
			System.out.println("Connected to remote HypeerWeb.");
		}
		else{
			hypeerweb.addNode(0);
			System.out.println(hypeerweb);
		}
		Runtime.getRuntime().addShutdownHook(new KillThread(hypeerweb));
		System.out.println("== Distributed HypeerWeb v 1.0 Creator ==");
		System.out.print("Enter the command: ");
		String userInput = in.readLine();
		Scanner scan;
		
	    while(!userInput.equalsIgnoreCase("quit")) {
	    	scan = new Scanner(userInput);
	    	String nextInput = scan.next();
	    	
	    	if(nextInput.equalsIgnoreCase("rem")){
	    		int nodeToRemove = scan.nextInt();
	    		System.out.println("Removing node \""+ nodeToRemove+"\" ...");
	    		hypeerweb.removeNode(getNode(nodeToRemove,hypeerweb));
	    	}
/*	    	else if (nextInput.equalsIgnoreCase("remlast")) {
	    		System.out.println("Removing the last node ... ");
	    		hypeerweb.removeNode(hypeerweb.getAllNodes().get(hypeerweb.getAllNodes().size()-1));
	    	}
*/	    	else if (nextInput.equalsIgnoreCase("sendMsg")){
	    		int startPt = scan.nextInt();
	    		int endPt = scan.nextInt();
	    		hypeerweb.sendMessage(getNode(startPt,hypeerweb), getNode(endPt,hypeerweb), new PrintOut());
	    	}
	    	else if (nextInput.equalsIgnoreCase("print")) {
	    		System.out.println(hypeerweb);
	    	}
	    	else if (nextInput.equalsIgnoreCase("printdb")) {
	    		System.out.println(ResidentDatabase.print());
	    	}
	    	else if(nextInput.equalsIgnoreCase("size")){
	    		hypeerweb.broadcastWithAck(hypeerweb.getMyConnection());
	    	}
	    	else {
	    		System.out.println("Adding node \"" + userInput + "\"");
	    		System.out.println(hypeerweb.addNode(userInput));	
	    	}
	    	System.out.print("\nEnter the command: ");
	    	userInput = in.readLine();
	    }
	    hypeerweb.terminate();
	}
	private static Node getNode(int address, Connection hypeerweb){
		return hypeerweb.getMyConnection().getNodeAt(new NodeAddress(address));
	}
	private static void Client(String[] args) {
		System.out.println("Acting as \"Client\"");
		Connection webConnection = new Connection(args[0],args[1]);
		Random numGen = new Random();
		int webSize = 0;
		
		while(webConnection.getWebSize()<=FINALCOUNT){
			int nextInt = numGen.nextInt(4);
			
			for(int i = 0; i<10; i++){
				webConnection.addNode(webSize++);
			}			
			
			switch(nextInt){
			case 0:{	//Add Node
				for(int i = 0; i<10; i++){
					webConnection.addNode(webSize++);
				}
				break;
			}
			case 1: {
				int removeNode = numGen.nextInt(webSize);
				Node toRemove = webConnection.getAllNodes().get(removeNode);
				if(toRemove.getAddress().getAddress()!=0){
					webConnection.removeNode(toRemove);
				}
				webSize--;
				break;
			}
			case 2: {
				int startNode = numGen.nextInt(webSize);
				int endNode = numGen.nextInt(webSize);
				webConnection.sendMessage(webConnection.getAllNodes().get(startNode), 
						webConnection.getAllNodes().get(endNode), new PrintOut());
				break;
			}
			case 3: {
				int broadcast = numGen.nextInt(webSize);
				webConnection.broadcast(webConnection.getAllNodes().get(broadcast));
				break;	
			}
			default: {
				System.out.println("Bad Place to be");
				break;
			}
			}
		}
	}

	private static void Driver(){
		System.out.println("Running \"Driver\"");
		Connection webConnection = new Connection();
		Random numGen = new Random();
		int webSize = 0;
		
		while(webConnection.getWebSize()<=FINALCOUNT){
			int nextInt = numGen.nextInt(4);
			
			for(int i = 0; i<8; i++){
				webConnection.addNode(webSize++);
			}			
			
			switch(nextInt){
			case 0:{	//Add Node
				for(int i = 0; i<5; i++){
					webConnection.addNode(webSize++);
				}
				System.out.println("size is :" + webSize);
				break;
			}
			case 1: {
				int removeNode = numGen.nextInt(webSize);
				Node toRemove = webConnection.getAllNodes().get(removeNode);
				if(toRemove.getAddress().getAddress()!=0){
					webConnection.removeNode(toRemove);
				}
				
				webSize--;
				System.out.println("size is :" + webSize);
				break;
			}
			case 2: {
				int startNode = numGen.nextInt(webSize);
				int endNode = numGen.nextInt(webSize);
				webConnection.sendMessage(webConnection.getAllNodes().get(startNode), 
						webConnection.getAllNodes().get(endNode), new PrintOut());
				break;
			}
			case 3: {
				int broadcast = numGen.nextInt(webSize);
				webConnection.broadcast(webConnection.getAllNodes().get(broadcast));
				break;	
			}
			default: {
				System.out.println("Bad Place to be");
				break;
			}
			
			}
		}
		System.out.println("Finished Driver");
		webConnection.terminate();
	}

}
